﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.IO;
using System.Xml;

using ParamSetCollection.General.Parameters.Normal;


namespace ParamSetCollection.General.Parameters.Alarms
{
    public enum AlarmLevelEnum
    {
        Information=0,  //Informational purposes. No stoppage.
        Warning,        //Warning. No stoppage
        Error,          //Error. Stoppage.
        Alarm           //Safety related Error. Stoppage.
    }

    public class AlarmUnit
    {
        #region============================== 变量 ====================================
        //报警状态改变

        public event OnAlarmStateChangeEventHandler OnStateChange;




        private bool m_enable = false;
        private bool m_editable = true;
        private AlarmLevelEnum m_level = AlarmLevelEnum.Error;
        private ushort m_actionSet = 1;//报警的响应动作

        public bool NewState = false;
        private bool m_activated = false;
        private string m_errCode = "0001";

        CommDataUnit m_commDataUnit = null;
        int m_bitIndex = 0;

        private Dictionary<string, string> m_nameDic = new Dictionary<string, string>();
        private Dictionary<string, string> m_msgDic = new Dictionary<string, string>();

        private string m_language = "en";
        #endregion====================================================================


        #region============================== 属性 ====================================

        public Dictionary<string, string> Names { get { return m_nameDic; }  }

        public Dictionary<string, string> Msgs { get { return m_msgDic; } }
        public bool Enable { get { return m_enable; } set { m_enable = value; } }
        public bool Editable { get { return m_editable; } set { m_editable = value; } }

        public ushort ActionSet { get { return m_actionSet; } set { m_actionSet = value; } }

        public AlarmLevelEnum Level { get { return m_level; } set { m_level = value; } }

        public string ErrorCode { get { return m_errCode; }set { m_errCode = value; } }

        public bool Activated
        {
            get { return m_activated; }
            set
            {
                if (m_activated != value)
                {
                    if (OnStateChange != null)
                    {
                        OnStateChange(Clone(value));
                    }
                    m_activated = value;


                }
            }
        }
        #endregion====================================================================


        #region============================= 内部变量 ================================




        #endregion===================================================================


        #region============================= 保护函数 ================================
        #endregion===================================================================


        #region============================= 公开函数 ================================
        public AlarmUnit(AlarmUnit desAu)
        {

            Editable = desAu.Editable;
            Enable = desAu.Enable;
            Activated = desAu.Activated;
            Level = desAu.Level;
            ActionSet = desAu.ActionSet;
            ErrorCode = desAu.ErrorCode;

            foreach (var key in desAu.Names.Keys)
            {
                Names.Add(key, desAu.Names[key]);
            }

            foreach (var key in desAu.Msgs.Keys)
            {
                Msgs.Add(key, desAu.Msgs[key]);
            }


        }

        public AlarmUnit()
        {

        }

        public void InputBindingStateData(CommDataUnit du, int bitIndex)
        {
            m_commDataUnit = du;
            if (m_commDataUnit != null)
            {
                m_bitIndex = bitIndex;
                m_commDataUnit = du;
                m_commDataUnit.OnRenew += M_commDataUnit_OnRenew;

            }


        }



        public static AlarmUnit GetAlarmUnit(XmlNode alNode,int count)//Alarm节点
        {
            AlarmUnit au = new AlarmUnit();
            au.m_bitIndex = count % 16;

            for (int i = 0; i < alNode.ChildNodes.Count; i++)
            {
                XmlNode pNod = alNode.ChildNodes[i];
                switch (pNod.Name)
                {
                    case "Editable":
                        bool e = false;
                        if(bool.TryParse(pNod.InnerText,out e))
                        {
                            au.Editable = e;
                        }
                        break;
                    case "Enable":
                        bool b = false;
                        if(bool.TryParse(pNod.InnerText,out b))
                        {
                            au.Enable = b;
                        }
                        break;
                    case "Level":
                        int t = 0;
                        if(int.TryParse(pNod.InnerText,out t))
                        {
                            au.Level = (AlarmLevelEnum)t;
                        }
                        break;
                    case "ErrorCode":
                        au.ErrorCode = pNod.InnerText;
                        break;
                    case "ActionSet":
                        ushort u = 0;
                        if(ushort.TryParse(pNod.InnerText, out u))
                        {
                            au.ActionSet = u;
                        }
                        break;
              
                    default:
                        if(pNod.Name.Contains("Name_"))
                        {
                            if(au.Names.ContainsKey(pNod.Name)==false)
                            {
                                au.Names.Add(pNod.Name, pNod.InnerText);
                            }
                        }
                        else if(pNod.Name.Contains("Tips_"))
                        {
                            if (au.Msgs.ContainsKey(pNod.Name) == false)
                            {
                                au.Msgs.Add(pNod.Name, pNod.InnerText);
                            }
                        }


                        break;
                }

            }

            return au;
        }

        public AlarmUnit Clone(bool newState)
        {
            AlarmUnit au = new AlarmUnit(this);
            au.NewState = newState;
            return au;
        }


        #endregion===================================================================

        #region============================= 事件函数 ================================
        private void M_commDataUnit_OnRenew()
        {
            ShortBits sbt = m_commDataUnit.Data;
            if (sbt[m_bitIndex] != m_activated)
            {
                //触发报警状态变更
                OnStateChange?.Invoke(this.Clone(sbt[m_bitIndex]));
                m_activated = sbt[m_bitIndex];
            }
        }

        #endregion===================================================================
    }
}
